package org.vectrics.logging;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.apache.ecs.html.Body;
import org.apache.ecs.html.Font;
import org.apache.ecs.html.Html;
import org.apache.log4j.spi.LoggingEvent;
import org.vectrics.common.html.Cell;
import org.vectrics.common.html.Row;
import org.vectrics.common.html.Table;
import org.vectrics.common.util.LocalMachineUtils;
import org.vectrics.config.ApplicationConfiguration;
import org.vectrics.config.MailConfiguration;
import org.vectrics.domain.Domain;
import org.vectrics.hibernate.ApplicationContext;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.mail.MailMessage;
import org.vectrics.mail.UserMailer;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.struts.PhraseProvider;
import org.vectrics.system.SystemService;
import org.vectrics.user.Person;
import org.vectrics.user.PersonSearchCriteria;
import org.vectrics.user.PersonService;

public class NotifyAppenderHandlerThread extends Thread {
	private List eventList = new ArrayList();
	private int accumulateTime = 15;
	private int maxMessageCount = 800;
	private boolean _blockFromFinishing = false;
	private boolean finishing = false;
	private SystemService systemService = null;
	private PersonService personService = null;
	private ApplicationConfiguration applicationConfiguration = null;
	private ApplicationContext applicationInformation  = null;
	private String hdrBackground = "#aaaabb";
	private String cellBackground = "#ddddff";
	
	
	public NotifyAppenderHandlerThread(ApplicationContext applicationInformation, SystemService systemService, PersonService personProvider,
			ApplicationConfiguration applicationConfiguration) {
		super();
		this.applicationInformation = applicationInformation;
		this.systemService = systemService;
		this.personService = personProvider;
		this.applicationConfiguration = applicationConfiguration;
	}

	public synchronized void addEvent(LoggingEvent event) {
		eventList.add(event);
	}

	public void blockFromFinishing() {
		this._blockFromFinishing =true;
	}
	
	public void releaseBlockFromFinishing() {
		this._blockFromFinishing = false;
	}
	
	public boolean isFinishing() {
		return(this.finishing);
	}
	
	public void run() {
		ThreadProperties.setApplicationContext(this.applicationInformation);
		int timeExpired = 0;
		while ((accumulateTime > timeExpired) || (eventList.size() >= this.maxMessageCount)
				|| (this._blockFromFinishing)){
			try {
				sleep(1000);
			} catch (Exception ex) {
				//Logger..warn("Exception sleeping thread", ex);
			}
			timeExpired++;
		}
		finishing = true;
		sendEvents(eventList);
	}
	
	public synchronized void sendEvents(List eventList) {
		PhraseProvider phraseProvider = CoreServiceLocator.getPhraseProvider(); 
		
		Domain systemDomain = systemService.findSystemDomain();
		MailConfiguration mailConfig = applicationConfiguration
				.getFromMailConfiguration(systemDomain);
		PersonSearchCriteria criteria = CoreServiceLocator.createPersonSearchCriteria();
		criteria.addPrivilege("notify.system.error");
		criteria.addDomain(systemDomain);
		criteria.setShowSystemUsers(true);
		Collection adminPeople = personService.findPersons(criteria, 0, 1000);
		
		String hostName = LocalMachineUtils.findHostName()
		   + "  /  " + LocalMachineUtils.findHostAddress();
		
		
		if (adminPeople.size() > 0) {
			Iterator iter = adminPeople.iterator();
			while (iter.hasNext()) {
				Person adminPerson = (Person)iter.next();
				if (adminPerson.createContactInfoIfNotExist().getEmail() != null) {
					Locale locale = adminPerson.getLocale().getLocale();
					if (locale == null)
						locale = CoreServiceLocator.getConfiguration().getDefaultLocale();
	
					MailMessage mailMessage = new MailMessage(systemDomain);
					mailMessage.setSubject("HEXACTA error in log - " + hostName);
			
					Html html = new Html();
					Body body = new Body();
					html.addElement(body);
					Font messageFont = this.createNormalFont();
					messageFont.addElement("<br>Error Messages"
							 + "<br><br>");
					body.addElement(messageFont);
					
					Table table = new Table();
					body.addElement(table);
					Row hdrRow = table.addRow();
					createHeaderCell(hdrRow, "Timestamp");
					createHeaderCell(hdrRow, "Severity");
					createHeaderCell(hdrRow, "Thread");
					createHeaderCell(hdrRow, "Category");
					createHeaderCell(hdrRow, "Message");
					
					Iterator eventIter = eventList.iterator();
					while (eventIter.hasNext()) {
						Row row = table.addRow();
						LoggingEvent event = (LoggingEvent)eventIter.next();
						
						//Locale defaultLocale = CoreServiceLocator.getConfiguration().getDefaultLocale(); 
						SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd hh:MM:ss");
						createNormalCell(row, dateFormat.format(new Date(event.timeStamp)));
						createNormalCell(row, event.getLevel().toString());
						createNormalCell(row, event.getThreadName());
						createNormalCell(row, event.getLoggerName());
						
						StringBuffer messageText = new StringBuffer();
						messageText.append((String)event.getMessage());
						String[] throwableLines = event.getThrowableStrRep();
						if ((throwableLines != null) && (throwableLines.length > 0)) {
							for (int i = 0; i < throwableLines.length; i++) {
								messageText.append("<br>");
								messageText.append(throwableLines[i]);
							}
							
						}
						createNormalCell(row, messageText.toString());
					}
					
					mailMessage.setBody(html.toString());
					mailMessage.setFromAddress("FlashRecruit");
					mailMessage.setFromName("FlashRecruit System");
					mailMessage.setContentType(MailMessage.CONTENT_HTML);
		
					UserMailer userMailer = new UserMailer(mailConfig);
					userMailer.sendMessage(adminPerson, mailMessage);
				}
			}
		}
		
	}

	private Cell createHeaderCell(Row hdrRow, String caption) {
		Cell hdrCell = hdrRow.addCell();
		hdrCell.setBgColor(hdrBackground);
		Font captionFont = this.createHdrFont();
		captionFont.addElement(caption);
		hdrCell.addElement(captionFont);
		return(hdrCell);
	}
	
	private Cell createNormalCell(Row hdrRow, String caption) {
		Cell hdrCell = hdrRow.addCell();
		hdrCell.setBgColor(cellBackground);
		Font captionFont = this.createNormalFont();
		captionFont.addElement(caption);
		hdrCell.addElement(captionFont);
		return(hdrCell);
	}
	
	private Font createNormalFont() {
		Font font = new Font();
		font.setStyle("font:normal 0.65em Verdana");
		return(font);
	}

	private Font createHdrFont() {
		Font font = new Font();
		font.setStyle("font:bold 0.65em Verdana");
		return(font);
	}
}
